package com.luhuiguo.cms.client.presenter;

import com.extjs.gxt.ui.client.binding.FormBinding;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.GlobalConstants;
import com.luhuiguo.cms.client.GlobalMessages;
import com.luhuiguo.cms.shared.event.ChannelCreatedEvent;
import com.luhuiguo.cms.shared.event.ChannelUpdatedEvent;
import com.luhuiguo.cms.shared.event.EditChannelCancelledEvent;
import com.luhuiguo.cms.shared.model.ChannelModel;
import com.luhuiguo.cms.shared.model.ChannelTreeModel;
import com.luhuiguo.cms.shared.rpc.CreateChannel;
import com.luhuiguo.cms.shared.rpc.CreateChannelResult;
import com.luhuiguo.cms.shared.rpc.UpdateChannel;
import com.luhuiguo.cms.shared.rpc.UpdateChannelResult;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.presenter.client.widget.WidgetDisplay;
import com.luhuiguo.gwt.presenter.client.widget.WidgetPresenter;

public class EditChannelPresenter extends WidgetPresenter<EditChannelPresenter.Display> {

    public interface Display extends WidgetDisplay {

        FormPanel getFormPanel();

        FormBinding getFormBinding();

        Button getSubmitButton();

        Button getCancelButton();

        TextField<String> getNameField();

    }

    private DispatcherAsync dispatcher;

    @SuppressWarnings("unused")
    private GlobalConstants constants;

    private GlobalMessages messages;

    private ChannelTreeModel channelTreeModel;

    private ChannelModel channelModel;

    @Inject
    public EditChannelPresenter(Display display, EventBus eventBus, DispatcherAsync dispatcher,
            GlobalConstants constants, GlobalMessages messages) {
        super(display, eventBus);
        this.dispatcher = dispatcher;
        this.constants = constants;
        this.messages = messages;
    }

    @Override
    protected void onBind() {
        display.getCancelButton().addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                // display.getFormPanel().reset();
                eventBus.fireEvent(new EditChannelCancelledEvent(channelTreeModel));
            }
        });

        display.getSubmitButton().addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                if (display.getFormPanel().isValid()) {
                    display.getFormPanel().mask();
                    if (null == channelModel.getId()) {
                        createChannel();
                    } else {
                        updateChannel();
                    }
                }
            }
        });

    }

    protected void updateChannel() {
        dispatcher.execute(new UpdateChannel(channelModel), new AsyncCallback<UpdateChannelResult>() {

            @Override
            public void onFailure(Throwable caught) {
                display.getFormPanel().unmask();
                MessageBox.alert(messages.error(), messages.saveChannelFailed(channelModel.getTitle()), null);
            }

            @Override
            public void onSuccess(UpdateChannelResult result) {
                display.getFormPanel().unmask();
                // display.getFormPanel().reset();
                eventBus.fireEvent(new ChannelUpdatedEvent(result.getNew(), channelTreeModel));

            }
        });
    }

    protected void createChannel() {
        dispatcher.execute(new CreateChannel(channelModel), new AsyncCallback<CreateChannelResult>() {

            @Override
            public void onFailure(Throwable caught) {
                display.getFormPanel().unmask();
                MessageBox.alert(messages.error(), messages.saveChannelFailed(channelModel.getTitle()), null);
            }

            @Override
            public void onSuccess(CreateChannelResult result) {
                display.getFormPanel().unmask();
                // display.getFormPanel().reset();
                eventBus.fireEvent(new ChannelCreatedEvent(result.get(), channelTreeModel));

            }
        });

    }

    @Override
    protected void onRevealDisplay() {

    }

    @Override
    protected void onUnbind() {

    }

    public void revealDisplay(ChannelTreeModel channelTreeModel, ChannelModel channelModel) {

        this.channelTreeModel = channelTreeModel;
        this.channelModel = channelModel;

        if (null == channelModel.getId()) {
            display.getNameField().setEnabled(true);
        } else {
            display.getNameField().setEnabled(false);
        }

        BeanModelFactory factory = BeanModelLookup.get().getFactory(ChannelModel.class);
        BeanModel model = factory.createModel(channelModel);

        display.getFormBinding().bind(model);
        revealDisplay();
    }

}
